package com.scshyzh.redis.lock;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.function.Function;

/**
 * 公平锁 RedissonFairLock
 * 多个锁： RedissonMultiLock  几个锁都获取到 了才能执行；
 * 读写锁：
 * @author: songkui
 * @since: 2022/6/28 11:07
 */
public class MochaRedisLockWrapper {

    @Autowired
    private RedissonClient redissonClient;


    /**
     * 非公平锁
     * @param lockInfo
     * @param function
     * @param <T>
     * @param <R>
     * @return
     * @throws Exception
     */
    public  <T, R> MochaRedissonLock.RedisLockResult<R> doLock(MochaRedissonLock<T> lockInfo, Function<T, MochaRedissonLock.RedisLockResult<R>> function)throws Exception{
        RLock lock = redissonClient.getLock(lockInfo.lockKey);
        try {
            if (lockInfo.waitTime == -1){
                if (lockInfo.leaseTime == -1){
                    lock.lock();
                   return function.apply(lockInfo.t);
                }
                lock.lock(lockInfo.leaseTime, lockInfo.unit);
                return function.apply(lockInfo.t);
            }

            if (lock.tryLock(lockInfo.waitTime, lockInfo.leaseTime, lockInfo.unit)){
                return function.apply(lockInfo.t);
            }else {
                return MochaRedissonLock.RedisLockResult.of(0, "Get lock timeout");
            }

        } catch (Exception e) {
           throw new Exception(e);
        }finally {
            if (lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }

}
